import { CustomPage, SortDropdown } from '@/components/index.jsx';
import { Card, Flex, Input, Form, Button } from 'antd';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import SearchForm from '@/components/SearchForm/index.jsx';
import { ResourceApi } from '@/api/resource/api.js';
import FileUpload from '@/components/FileUpload/index.jsx';
import { SPACE } from '@/constants/themeConstant.js';
import {
  CheckSquareOutlined,
  DeleteOutlined,
  FolderOpenOutlined,
  ReloadOutlined,
  SnippetsOutlined,
  UploadOutlined
} from '@ant-design/icons';
import StringUtil from '@/utils/string.js';
import ModalUtil from '@/utils/modal.js';
import DirBreadcrumb from '@/pages/FileManage/widget/DirBreadcrumb/index.jsx';
import DayjsUtil from '@/utils/dayjs.js';
import UiUtil from '@/utils/ui.js';
import { getName } from '@/pages/FileManage/fun.js';
import { useUiStore } from '@/store/index.js';
import CardList from '@/components/CardList/index.jsx';
import RenameModal from '@/pages/FileManage/widget/RenameModal/index.jsx';
import FileModal from '@/pages/FileManage/widget/FileModal/index.jsx';
import FileItem from '@/pages/FileManage/widget/FileItem/index.jsx';
import FileContextMenu from '@/pages/FileManage/widget/FileContextMenu/index.jsx';
import { useUpdateEffect } from 'ahooks';
import useHashParams from '@/hooks/useHashParams.js';
import { INDEX_ROUTE } from '@/constants/pageConstant.js';
import { useNavigate } from 'react-router-dom';
import { cancelRequest, getRequestId } from '@/utils/request.js';

const requestId = getRequestId();

export default function FileManage() {
  // 卡片列表
  const listRef = useRef();
  // 搜索条件
  const [searchQuery, setSearchQuery] = useState();
  // 文件信息弹窗
  const fileModalRef = useRef();
  // 重命名弹窗
  const renameModalRef = useRef();
  // 剪切的文件
  const cutFile = useUiStore((s) => s.cutFile);
  // 每页显示数量
  const pageSize = 48;
  // 页面参数
  const { pId } = useHashParams();
  // 是否多选
  const [multiple, setMultiple] = useState(false);
  // 选中的行
  const [selectedRows, setSelectedRows] = useState([]);
  // 路由控制
  const navigate = useNavigate();
  // 字段排序
  const [sort, setSort] = useState({
    sortBy: 'create_time',
    isAsc: false
  });

  useEffect(() => {
    if (searchQuery) {
      listRef.current?.request();
    }
  }, [searchQuery]);

  useUpdateEffect(() => {
    listRef.current?.request();
  }, [sort]);

  useUpdateEffect(() => {
    if (pId != null) {
      listRef.current?.request();
    }
  }, [pId]);

  // 获取父级ID
  const getPId = useCallback(() => {
    return StringUtil.isNumeric(pId) ? pId : 0;
  }, [pId]);

  // 请求数据
  const getData = useCallback(
    async (page) => {
      // 取消上一次请求
      cancelRequest(requestId);
      const pageNo = page?.pageNo || 1;
      const pageSize = page?.pageSize || pageSize;
      const { code, data } = await ResourceApi.getList(
        {
          pageNo: pageNo,
          pageSize: pageSize,
          searchQuery: {
            ...searchQuery,
            parentResourceId: getPId()
          },
          sortBy: sort.sortBy,
          isAsc: sort.isAsc
        },
        requestId
      );
      const { list, total } = data;
      return Promise.resolve({
        data: list,
        success: code === 0,
        total: total
      });
    },
    [searchQuery, pId, sort]
  );

  // 创建文件夹
  function createDir() {
    ModalUtil.confirm('确定要创建文件夹吗？', () => {
      ResourceApi.createDir(`新建文件夹${DayjsUtil.getCurrentDatetimeId()}`, getPId()).then(
        ({ code }) => {
          if (code === 0) {
            ModalUtil.success('创建文件夹成功');
            listRef.current?.request();
          }
        }
      );
    });
  }

  // 剪切文件
  function cutFileTo(data) {
    useUiStore.getState().setCutFile(data);
  }

  // 粘贴文件
  function pasteFile() {
    if (cutFile?.resourceId == null) {
      ModalUtil.error('文件不存在，无法粘贴');
      cutFileTo(null);
      return;
    }
    UiUtil.showLoading('粘贴中...');
    ResourceApi.update(cutFile?.resourceId, {
      parentResourceId: getPId()
    })
      .then(({ code }) => {
        if (code === 0) {
          ModalUtil.success('操作成功');
          listRef.current?.request();
          cutFileTo(null);
        }
        UiUtil.hideLoading();
      })
      .catch(() => {
        UiUtil.hideLoading();
      });
  }

  // 批量删除
  function deleteBatch() {
    ModalUtil.confirm(`确定要删除选中的${selectedRows?.length ?? 0}个文件吗？`, () => {
      const ids = selectedRows.map((row) => row?.resourceId);
      UiUtil.showLoading('删除中...');
      ResourceApi.deleteByIds(ids)
        .then((res) => {
          const { code, msg } = res;
          if (code === 0) {
            ModalUtil.success(msg);
            // 刷新列表
            listRef.current?.request();
            // 清空选中行
            listRef.current?.setSelectedRows([]);
          } else {
            ModalUtil.error(msg);
          }
          UiUtil.hideLoading();
        })
        .catch(() => {
          UiUtil.hideLoading();
        });
    });
  }

  // 批量粘贴文件
  function pasteBatch() {
    ModalUtil.confirm(`确定要粘贴选中的${selectedRows?.length ?? 0}个文件吗？`, async () => {
      UiUtil.showLoading('粘贴中...');
      for (let i = 0; i < selectedRows.length; i++) {
        const rows = selectedRows[i];
        const id = rows?.resourceId;
        // 计算进度
        const progress = Math.floor(((i + 1) / selectedRows.length) * 100);
        if (`${rows.parentResourceId}` === `${getPId()}`) {
          UiUtil.setProgress(progress);
          continue;
        }
        await ResourceApi.update(id, {
          parentResourceId: getPId()
        }).catch(() => {
          UiUtil.hideLoading();
        });
        UiUtil.setProgress(progress);
      }
      UiUtil.hideLoading();
      ModalUtil.success('操作成功');
      listRef.current?.request();
      listRef.current?.setSelectedRows([]);
    });
  }

  // 面包屑导航
  const getDirBreadcrumbMemo = useMemo(() => <DirBreadcrumb pId={getPId()} />, [pId]);

  // 重命名窗口
  const getRenameModal = useMemo(
    () => <RenameModal ref={renameModalRef} onRefresh={() => listRef.current?.request()} />,
    []
  );

  // 属性窗口
  const getFileModal = useMemo(() => <FileModal ref={fileModalRef} />, []);

  // 工具栏
  const getToolbar = useMemo(() => {
    const width = 150;
    return (
      <Card style={{ marginBottom: 'var(--ant-margin)' }}>
        <Flex gap={SPACE} justify="space-between">
          <SearchForm
            onSearch={(values) => {
              listRef.current?.setPageNo(1);
              setSearchQuery(values);
            }}
            formItems={
              <>
                <Form.Item label="文件名" name="resourceName">
                  <Input placeholder="请输入文件名" style={{ width: width }} />
                </Form.Item>
              </>
            }
          />
          <Flex gap={SPACE}>
            <SortDropdown
              defaultField="create_time"
              defaultSort="desc"
              fieldMap={{
                create_time: '创建时间',
                update_time: '最近修改',
                size: '文件大小'
              }}
              onChange={(field, order) => {
                setSort({ sortBy: field, isAsc: order === 'asc' });
              }}
            />
            <Button
              type="primary"
              icon={<SnippetsOutlined />}
              onClick={pasteFile}
              disabled={multiple || cutFile?.resourceId == null}
            >
              粘贴
              {cutFile != null ? <>({getName(cutFile)})</> : null}
            </Button>
            <Button
              type={multiple ? 'primary' : 'default'}
              icon={<CheckSquareOutlined />}
              onClick={() => setMultiple(!multiple)}
            >
              {multiple ? `取消多选` : '多选'}
            </Button>
            {multiple && (
              <>
                <Button type="primary" danger icon={<DeleteOutlined />} onClick={deleteBatch}>
                  批量删除({selectedRows?.length ?? 0})
                </Button>
                <Button type="primary" icon={<SnippetsOutlined />} onClick={pasteBatch}>
                  粘贴到目录({selectedRows?.length ?? 0})
                </Button>
              </>
            )}
            <FileUpload
              pId={getPId()}
              onSuccess={() => {
                listRef.current?.request();
              }}
              render={(loading) => (
                <Button type="primary" loading={loading} icon={<UploadOutlined />}>
                  上传文件
                </Button>
              )}
            />
            <Button type="primary" icon={<FolderOpenOutlined />} onClick={createDir}>
              创建文件夹
            </Button>
            <Button
              type="primary"
              icon={<ReloadOutlined />}
              onClick={() => {
                listRef.current?.request();
              }}
            >
              刷新
            </Button>
          </Flex>
        </Flex>
      </Card>
    );
  }, [cutFile, multiple, selectedRows, pId]);

  return (
    <CustomPage>
      {getRenameModal}
      {getFileModal}
      {getToolbar}
      {getDirBreadcrumbMemo}
      <CardList
        ref={listRef}
        column={12}
        rowKey="resourceId"
        multiple={multiple}
        grid={{
          xs: 1,
          md: 2,
          lg: 4
        }}
        request={getData}
        pagination={{
          pageSize
        }}
        hoverable
        onClickCard={(data) => {
          if (data?.resourceType === 'directory') {
            // 跳转到子目录
            navigate(`${INDEX_ROUTE}/file-manager#pId=${data?.resourceId}`);
          } else {
            fileModalRef.current?.open(data);
          }
        }}
        onSelectedRowsChange={(rows) => {
          setSelectedRows(rows);
        }}
        addCardBox={(data, card) => {
          return (
            <FileContextMenu
              data={data}
              onRefresh={() => listRef.current?.request()}
              onAttributes={() => fileModalRef.current?.open(data)}
              onRename={() => renameModalRef.current?.open(data)}
            >
              {card}
            </FileContextMenu>
          );
        }}
        renderItem={(data) => {
          return <FileItem data={data} />;
        }}
      />
    </CustomPage>
  );
}
